Fix up dev-dependencies
authorYehuda Katz + Carl Lerche <engineering@tilde.io>
Thu, 3 Jul 2014 01:13:00 +0000 (18:13 -0700)
committerAlex Crichton <alex@alexcrichton.com>
Thu, 3 Jul 2014 19:42:18 +0000 (12:42 -0700)
Makefile
libs/toml-rs
src/cargo/core/package.rs
src/cargo/core/summary.rs
src/cargo/ops/cargo_rustc.rs
src/cargo/util/dependency_queue.rs
src/cargo/util/toml.rs
tests/test_cargo_compile_path_deps.rs

index 3faf405a795db867eb7e0271a50c04bf054e67ed..f3c7ffa8a052b12ee1bb993571f90d83a7e9ffd0 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -66,7 +66,7 @@ target/tests/test-integration: $(HAMCREST) $(TEST_SRC) $(BIN_TARGETS)
 
 target/tests/test-unit: $(TOML) $(HAMCREST) $(SRC) $(HAMMER)
        mkdir -p target/tests
-       $(RUSTC) --test $(RUSTC_FLAGS) $(TEST_DEPS) -o $@ src/cargo/lib.rs
+       $(RUSTC) --test -g $(RUSTC_FLAGS) $(TEST_DEPS) -o $@ src/cargo/lib.rs
 
 test-unit: target/tests/test-unit
        target/tests/test-unit $(only)
index 713816102b1cb61f45d2306f38e3d95dfdcc8ae1..6e0701caa513e11f939899c4d6c258537796c0d3 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 713816102b1cb61f45d2306f38e3d95dfdcc8ae1
+Subproject commit 6e0701caa513e11f939899c4d6c258537796c0d3
index 8feae143c293b238fff19daaa92fa42ac5bb5fea..275cc26b45e543f59ff5d08702ce64d3676cb6fa 100644 (file)
@@ -18,7 +18,7 @@ use serialize::{Encoder,Encodable};
 use core::source::{SourceId, SourceSet, Source};
 
 // TODO: Is manifest_path a relic?
-#[deriving(Clone,PartialEq)]
+#[deriving(Clone)]
 pub struct Package {
     // The package's manifest
     manifest: Manifest,
@@ -138,6 +138,12 @@ impl Show for Package {
     }
 }
 
+impl PartialEq for Package {
+    fn eq(&self, other: &Package) -> bool {
+        self.get_package_id() == other.get_package_id()
+    }
+}
+
 #[deriving(PartialEq,Clone,Show)]
 pub struct PackageSet {
     packages: Vec<Package>,
index 3a944ffd6b8c7c558bc064b55290f9ccea63810d..5d86a3e8d0d0f45528ef42519ca72ce6ac738de5 100644 (file)
@@ -15,7 +15,7 @@ impl Summary {
     pub fn new(pkg_id: &PackageId, dependencies: &[Dependency]) -> Summary {
         Summary {
             package_id: pkg_id.clone(),
-            dependencies: Vec::from_slice(dependencies)
+            dependencies: Vec::from_slice(dependencies),
         }
     }
 
index 1695c95cefcd5d9d79587f97c0d4ab291e03c53c..6c6218cf15da9ecdc5939278c0fc062e7c730bec 100644 (file)
@@ -201,6 +201,8 @@ fn rustc(root: &Path, target: &Target,
     let primary = cx.primary;
     let rustc = prepare_rustc(root, target, crate_types, cx);
 
+    log!(5, "command={}", rustc);
+
     proc() {
         if primary {
             rustc.exec().map_err(|err| human(err.to_str()))
@@ -262,6 +264,9 @@ fn execute(config: &mut Config,
     let pool = TaskPool::new(config.jobs());
     let (tx, rx) = channel();
     let mut queue = DependencyQueue::new();
+    for &(pkg, _) in jobs.iter() {
+        queue.register(pkg);
+    }
     for (pkg, (fresh, job)) in jobs.move_iter() {
         queue.enqueue(pkg, fresh, (pkg, job));
     }
@@ -303,5 +308,7 @@ fn execute(config: &mut Config,
         }
     }
 
+    log!(5, "rustc jobs completed");
+
     Ok(())
 }
index 689195b52c694f9f32dbecbefcf15a362c16fd48..1f4d29be5cc57576302b64fe551efb9bb221db37 100644 (file)
@@ -57,6 +57,13 @@ impl<T> DependencyQueue<T> {
         }
     }
 
+    /// Registers a package with this queue.
+    ///
+    /// Only registered packages will be returned from dequeue().
+    pub fn register(&mut self, pkg: &Package) {
+        self.reverse_dep_map.insert(pkg.get_name().to_str(), HashSet::new());
+    }
+
     /// Adds a new package to this dependency queue.
     ///
     /// It is assumed that any dependencies of this package will eventually also
@@ -72,6 +79,10 @@ impl<T> DependencyQueue<T> {
         let mut my_dependencies = HashSet::new();
         for dep in pkg.get_dependencies().iter() {
             if dep.get_name() == pkg.get_name() { continue }
+            // skip deps which were filtered out as part of resolve
+            if !self.reverse_dep_map.find_equiv(&dep.get_name()).is_some() {
+                continue
+            }
 
             let name = dep.get_name().to_str();
             assert!(my_dependencies.insert(name.clone()));
index 391fd11b0326cd552e574b1e14745203a28434f8..15a4e11d561d7d0f8323d23de97b3f9b65137593 100644 (file)
@@ -58,26 +58,25 @@ pub fn to_manifest(contents: &[u8],
 pub fn parse(toml: &str, file: &str) -> CargoResult<toml::Table> {
     let mut parser = toml::Parser::new(toml.as_slice());
     match parser.parse() {
-        Some(toml) => Ok(toml),
-        None => {
-            let mut error_str = format!("could not parse input TOML\n");
-            for error in parser.errors.iter() {
-                let (loline, locol) = parser.to_linecol(error.lo);
-                let (hiline, hicol) = parser.to_linecol(error.hi);
-                error_str.push_str(format!("{}:{}:{}{} {}\n",
-                                           file,
-                                           loline + 1, locol + 1,
-                                           if loline != hiline || locol != hicol {
-                                               format!("-{}:{}", hiline + 1,
-                                                       hicol + 1)
-                                           } else {
-                                               "".to_string()
-                                           },
-                                           error.desc).as_slice());
-            }
-            Err(human(error_str))
-        }
+        Some(toml) => return Ok(toml),
+        None => {}
     }
+    let mut error_str = format!("could not parse input TOML\n");
+    for error in parser.errors.iter() {
+        let (loline, locol) = parser.to_linecol(error.lo);
+        let (hiline, hicol) = parser.to_linecol(error.hi);
+        error_str.push_str(format!("{}:{}:{}{} {}\n",
+                                   file,
+                                   loline + 1, locol + 1,
+                                   if loline != hiline || locol != hicol {
+                                       format!("-{}:{}", hiline + 1,
+                                               hicol + 1)
+                                   } else {
+                                       "".to_string()
+                                   },
+                                   error.desc).as_slice());
+    }
+    Err(human(error_str))
 }
 
 type TomlLibTarget = TomlTarget;
@@ -163,8 +162,8 @@ impl TomlManifest {
             };
 
             // Collect the deps
-            try!(process_dependencies(&mut cx, self.dependencies.as_ref()));
-            try!(process_dependencies(&mut cx, self.dev_dependencies.as_ref()));
+            try!(process_dependencies(&mut cx, false, self.dependencies.as_ref()));
+            try!(process_dependencies(&mut cx, true, self.dev_dependencies.as_ref()));
         }
 
         let project = self.project.as_ref().or_else(|| self.package.as_ref());
@@ -184,49 +183,52 @@ impl TomlManifest {
     }
 }
 
-fn process_dependencies<'a>(cx: &mut Context<'a>,
+fn process_dependencies<'a>(cx: &mut Context<'a>, dev: bool,
                             new_deps: Option<&HashMap<String, TomlDependency>>)
                             -> CargoResult<()> {
-    match new_deps {
-        Some(ref dependencies) => {
-            for (n, v) in dependencies.iter() {
-                let (version, source_id) = match *v {
-                    SimpleDep(ref string) => {
-                        (Some(string.clone()), SourceId::for_central())
-                    },
-                    DetailedDep(ref details) => {
-                        let reference = details.branch.clone()
-                            .or_else(|| details.tag.clone())
-                            .or_else(|| details.rev.clone())
-                            .unwrap_or_else(|| "master".to_str());
-
-                        let new_source_id = match details.git {
-                            Some(ref git) => {
-                                let kind = GitKind(reference.clone());
-                                let loc = try!(Location::parse(git.as_slice()));
-                                let source_id = SourceId::new(kind, loc);
-                                // TODO: Don't do this for path
-                                cx.source_ids.push(source_id.clone());
-                                Some(source_id)
-                            }
-                            None => {
-                                details.path.as_ref().map(|path| {
-                                    cx.nested_paths.push(Path::new(path.as_slice()));
-                                    cx.source_id.clone()
-                                })
-                            }
-                        }.unwrap_or(SourceId::for_central());
-
-                        (details.version.clone(), new_source_id)
+    let dependencies = match new_deps {
+        Some(ref dependencies) => dependencies,
+        None => return Ok(())
+    };
+    for (n, v) in dependencies.iter() {
+        let (version, source_id) = match *v {
+            SimpleDep(ref string) => {
+                (Some(string.clone()), SourceId::for_central())
+            },
+            DetailedDep(ref details) => {
+                let reference = details.branch.clone()
+                    .or_else(|| details.tag.clone())
+                    .or_else(|| details.rev.clone())
+                    .unwrap_or_else(|| "master".to_str());
+
+                let new_source_id = match details.git {
+                    Some(ref git) => {
+                        let kind = GitKind(reference.clone());
+                        let loc = try!(Location::parse(git.as_slice()));
+                        let source_id = SourceId::new(kind, loc);
+                        // TODO: Don't do this for path
+                        cx.source_ids.push(source_id.clone());
+                        Some(source_id)
+                    }
+                    None => {
+                        details.path.as_ref().map(|path| {
+                            cx.nested_paths.push(Path::new(path.as_slice()));
+                            cx.source_id.clone()
+                        })
                     }
-                };
+                }.unwrap_or(SourceId::for_central());
 
-                cx.deps.push(try!(Dependency::parse(n.as_slice(),
-                                                 version.as_ref().map(|v| v.as_slice()),
-                                                 &source_id)))
+                (details.version.clone(), new_source_id)
             }
-        }
-        None => ()
+        };
+
+        let mut dep = try!(Dependency::parse(n.as_slice(),
+                       version.as_ref().map(|v| v.as_slice()),
+                       &source_id));
+
+        if dev { dep = dep.as_dev() }
+
+        cx.deps.push(dep)
     }
 
     Ok(())
index 16cde69b3d1f9f02658a451704fe4e824b068ec2..eb02258a3fd49a1249b7878368ae98bffa14a5ba 100644 (file)
@@ -85,7 +85,58 @@ test!(cargo_compile_with_nested_deps_shorthand {
       execs().with_stdout("test passed\n"));
 })
 
-test!(cargo_compile_with_dev_deps {
+test!(cargo_compile_with_root_dev_deps {
+    let p = project("foo")
+        .file("Cargo.toml", r#"
+            [project]
+
+            name = "foo"
+            version = "0.5.0"
+            authors = ["wycats@example.com"]
+
+            [dev-dependencies.bar]
+
+            version = "0.5.0"
+            path = "bar"
+
+            [[bin]]
+
+            name = "foo"
+        "#)
+        .file("src/foo.rs",
+              main_file(r#""{}", bar::gimme()"#, ["bar"]).as_slice())
+        .file("bar/Cargo.toml", r#"
+            [project]
+
+            name = "bar"
+            version = "0.5.0"
+            authors = ["wycats@example.com"]
+
+            [[lib]]
+
+            name = "bar"
+        "#)
+        .file("bar/src/bar.rs", r#"
+            pub fn gimme() -> &'static str {
+                "zoidberg"
+            }
+        "#)
+        ;
+
+    assert_that(p.cargo_process("cargo-build"),
+        execs().with_stdout(format!("{} bar v0.5.0 (file:{})\n\
+                                     {} foo v0.5.0 (file:{})\n",
+                                    COMPILING, p.root().display(),
+                                    COMPILING, p.root().display())));
+
+    assert_that(&p.bin("foo"), existing_file());
+
+    assert_that(
+      cargo::util::process(p.bin("foo")),
+      execs().with_stdout("zoidberg\n"));
+})
+
+test!(cargo_compile_with_transitive_dev_deps {
     let p = project("foo")
         .file("Cargo.toml", r#"
             [project]